package exampleclient;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import cageballclient.AI;
import cageballcommon.messages.Ball;
import cageballcommon.messages.InitPlayer;
import cageballcommon.messages.InitTeam;
import cageballcommon.messages.Player;
import cageballcommon.messages.Position;
import cageballcommon.messages.State;
import cageballcommon.messages.Team;
import javax.vecmath.Vector2f;

public class ExampleAI implements AI {

    private InitTeam otherTeam;
    private State last = null;
    private State current = null;

    public InitTeam initMyTeam(Properties properties) {
        List<InitPlayer> players = new ArrayList<InitPlayer>();
        //for(int i = new Integer(properties.getProperty("teamMembers")); i>0; i--) {}

        players.add(new InitPlayer("Viktor", 0, 500, 250));
        players.add(new InitPlayer("Dain", 1, 500, 400));
        players.add(new InitPlayer("Markus", 2, 500, 340));
        players.add(new InitPlayer("Shytoon", 3, 10, 350));

        return new InitTeam("The New Kotts", players);
    }

    public void initOtherTeam(InitTeam otherTeam) {
        this.otherTeam = otherTeam;
    }

    private boolean hitGoal() {

        if(last == null){
            return false;
        }
        Vector2f dir = new Vector2f(last.getBall().getX() - current.getBall().getX(), last.getBall().getY() - current.getBall().getY());
        Vector2f right = new Vector2f(last.getBall().getX(), last.getBall().getY() - 450);
        Vector2f left = new Vector2f(last.getBall().getX(), last.getBall().getY() - 250);
        Vector2f normal = new Vector2f(0, 1);

        normal.normalize();
        dir.normalize();
        right.normalize();
        left.normalize();

        float angleDir = normal.angle(dir);
        float angleRight = normal.angle(right);
        float angleLeft = normal.angle(left);

        if (angleDir > angleRight && angleDir > angleLeft && dir.x < 0) {
            return true;
        }

        return false;
    }

    public float getGoalHit(){
        Vector2f dir = new Vector2f(last.getBall().getX() - current.getBall().getX(), last.getBall().getY() - current.getBall().getY());
        dir.normalize();

        float factor = -current.getBall().getX()/dir.x;

        return dir.y*factor + current.getBall().getY();
    }

    public void act(State state) {
        current = state;
        Ball ball = state.getBall();
        Player closest = closest(state.getMyTeam());

        for (Player p : state.getMyTeam().getPlayers()) {

            if (p.getId() == closest.getId()) {
                p.kick(1200, 350, 0.9f);
            } else {
                p.kick(closest, 0.7f);
            }

            if (p.getId() == 3) {

                if (distance(new Pos(0, 350), ball) < 200) {
                    p.move(ball);
                } else if(hitGoal()){
                    p.move(10, getGoalHit());
                } else{
                    p.move(0.2f * ball.getX(), (ball.getY() - 350) * 0.2f + 350);
                }

                p.kick(getPlayer(2, state.getMyTeam()), 0.7f);

            } else if (p.getId() == 2) {
                if (ball.getX() < 600) {
                    p.move(ball.getX(), ball.getY());
                } else {
                    p.move(600, ball.getY());
                }

                if (distance(getPlayer(0, state.getMyTeam()), ball) < distance(getPlayer(1, state.getMyTeam()), ball)) {
                    p.kick(getPlayer(0, state.getMyTeam()), 0.7f);
                } else {
                    p.kick(getPlayer(1, state.getMyTeam()), 0.7f);
                }
            } else if (p.getId() == 1) {
                if (ball.getY() > 350) {

                    if (ball.getX() < 600) {
                        p.move(600, 350);
                    } else {
                        p.move(ball.getX(), 350);
                    }

                } else {
                    if (ball.getX() < 600) {
                        p.move(600, ball.getY());
                    } else {
                        p.move(ball.getX(), ball.getY());
                    }
                }

                p.kick(1200, 350, 0.7f);
            } else {
                if (ball.getY() < 350) {

                    if (ball.getX() < 600) {
                        p.move(600, 350);
                    } else {
                        p.move(ball.getX(), 350);
                    }
                } else {
                    if (ball.getX() < 600) {
                        p.move(600, ball.getY());
                    } else {
                        p.move(ball.getX(), ball.getY());
                    }
                }
                p.kick(1200, 350, 0.7f);
            }



        }

        last = state;
    }

    private Player getPlayer(int id, Team team) {
        for (Player player : team.getPlayers()) {
            if (player.getId() == id) {
                return player;
            }
        }

        return null;
    }

    private boolean closestToBall(Player player, Ball ball, Team team) {
        float distance = distance(player, ball);

        for (Player p : team.getPlayers()) {
            if (p != player) {
                if (distance > distance(p, ball)) {
                    return false;
                }
            }
        }

        return true;
    }

    private Player closest(Team team) {
        Player tmp = null;
        for (Player p : team.getPlayers()) {
            if (tmp == null) {
                tmp = p;
            } else {
                if (tmp.getX() < p.getX()) {
                    tmp = p;
                }
            }
        }

        return tmp;
    }

    private float distance(Position a, Position b) {
        float x = a.getX() - b.getX();
        float y = a.getY() - b.getY();

        return (float) Math.sqrt(x * x + y * y);
    }
}
